/*
 *  Player.cpp
 *  GLRender
 *
 *  Created by Patrick zulian on 5/4/10.
 *  Copyright 2010 University  of Lugano. All rights reserved.
 *
 */

#include "Player.h"
#include "Projectile.h"
#include "Bonus.h"

Player::Player(){
	theta = 3.14/200.0;
	this->_spaceShip=new SpaceShip(this,globals::PLAYER_INITIAL_POSITION, globals::PLAYER_VELOCITY);
	_objective=new WTarget(Point3d(0,0,-100));
	lastShoot = 0;
	_canShoot = true;
	weapon = new Projectile(this);
}

Weapon *
Player::shoot (double time)
{
	lastShoot = time;
	return weapon->generate(this);
}

void
Player::step(double tau){
	_spaceShip->step(tau);
	
	if((_spaceShip->position() -_objective->position()).norm() < (_objective->getRadius() + _spaceShip->getRadius())){
		_hasWin=true;
	}
}

WObject * 
Player::getObject()
{
	return _spaceShip;	
}

void Player::moveLeft(){
	_spaceShip->yaw(theta);
}

void Player::moveRight(){
	_spaceShip->yaw(-theta);
}

void Player::moveUp(){
	_spaceShip->pitch(theta);
}

void Player::moveDown(){
	_spaceShip->pitch(-theta);
}


void Player::accelerate(){
	_spaceShip->speedUp();
}

void Player::brake(){
	_spaceShip->speedDown();
}


void 
Player::rollCounterClockwise()
{
	_spaceShip->roll(-theta);
}

void 
Player::rollClockwise()
{
	_spaceShip->roll(theta);
}


void Player::renderOn(AbstractRenderer *renderer){
	_objective->renderOn(renderer);
	
	renderer->renderCockpit(this);
}

Point3d Player::getRadarTarget(){
	const Point3d pos = _spaceShip->position(), objPos = _objective->position();
	
	//use only x and z coordinates
	Point2d dir2target(pos.x() - objPos.x(), pos.z() - objPos.z());
	Point2d shipDir(_spaceShip->velocity().x(), _spaceShip->velocity().z());
	
	
	const double distance = dir2target.norm();
	
	//normalize vectors
	shipDir.normalize();
	dir2target /= distance;
	
	const double scale = distance/std::max< double >(100.0, distance);
	
	//coordinates of the target marker
	double cosangle = shipDir * dir2target;
	double sinangle = shipDir ^ dir2target;
	
	
	Point3d targetPos(sinangle, -cosangle, 0.0);
	targetPos*=scale;
	return targetPos;
}

Point3d
Player::getTargetVector(){
	Point3d tmp=_objective->position() - _spaceShip->position(); 
	tmp.normalize();
	return tmp;
}

double
Player::getTargetAltitude(){//
//	const Point3d pos = _spaceShip->position(), objPos = _objective->position();
//	
//	return std::max< double >(-1.0, std::min< double >(1.0, (pos.y() - objPos.y())/100.0));
	
	Point3d dirToTarget = _objective->position() - _spaceShip->position();
	Point3d shipDir = _spaceShip->velocity();
	
	dirToTarget.normalize(); shipDir.normalize();
	return dirToTarget * shipDir;
	
}



double
Player::getAlpha(){
	return _spaceShip->rotationAngle() + 90.0;
}

void
Player::checkShoot (double timeElapsed, double tau)
{
	_canShoot = (timeElapsed - this->lastShoot > tau*weapon->getRechargeTime());
}

bool
Player::canShoot () { return _canShoot || lastShoot == 0; }


